#pragma once
#include<iostream>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<vector>
#include<assert.h>
using namespace std;
typedef double dtype; 
typedef vector<dtype> vtype;

class problem {
public:
	problem(int n_val, int n_arg); 
	problem(const vtype& val, const vtype& arg);

	virtual vtype func(const vtype& input, const vtype& args, dtype t) = 0;

	void set_arg(const vtype& arg); 
	void set_val(const vtype& val); 

	inline vtype arg() { return arg_; }
	inline vtype val() { return val_; }

	inline dtype& arg(int index) { return arg_[index]; }
	inline dtype& val(int index) { return val_[index]; }

protected:
	vtype arg_; 
	vtype val_; 
};

class solver {
public:
	solver(shared_ptr<problem> prob) : prob_(prob){}
	virtual const vector<vtype> solve(int n, dtype h);

protected:
	virtual vtype step(dtype h, dtype t) = 0;
	shared_ptr<problem> prob_;
};
